/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.yami.shop.api.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.yami.shop.bean.app.dto.*;
import com.yami.shop.bean.app.param.OrderParam;
import com.yami.shop.bean.app.param.OrderShopParam;
import com.yami.shop.bean.app.param.SubmitOrderParam;
import com.yami.shop.bean.event.ConfirmOrderEvent;
import com.yami.shop.bean.model.Order;
import com.yami.shop.bean.model.UserAddr;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.util.Arith;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.service.*;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import cn.hutool.core.bean.BeanUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import com.yami.shop.common.response.ServerResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import jakarta.validation.Valid;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author lanhai
 */
@RestController
@RequestMapping("/p/order")
@Tag(name = "订单接口")
public class OrderController {

    @Autowired
    private OrderService orderService;
    @Autowired
    private SkuService skuService;
    @Autowired
    private ProductService productService;
    @Autowired
    private UserAddrService userAddrService;
    @Autowired
    private BasketService basketService;
    @Autowired
    private ApplicationContext applicationContext;
    @Autowired
    private ObjectMapper objectMapper;


    /**
     * 计算额外费用
     */
    private double calculateAdditionalFee(Double oriPrice, OrderParam orderParam) {
        double manyRelatedFee = 0.0;  // many相关金额总和
        double cloudVideoFee = 0.0;   // needCloudVideo相关金额
        double returnFee = 0.0;       // needReturn相关金额
        double addXRMFee = 0.0;
        double sEMTsetTimeFee = 0.0;   // SEMTsetTime 相关金额

        String orderConfigJson = orderParam.getOrderItem().getOrderConfigJson();
        Integer prodCount = orderParam.getOrderItem().getProdCount();

        if (orderConfigJson == null || orderConfigJson.isEmpty()) {
            return 0.0;
        }

        try {
            JsonNode rootNode = objectMapper.readTree(orderConfigJson);
            if (rootNode.isArray()) {


                // 单独做计算逻辑
                Integer testTime = 0;
                Integer joinTimes = 1;
                Boolean isXRMNormal = Boolean.FALSE;
                Boolean isXRM = Boolean.FALSE;
                Integer XRMCount = 0;

                for (JsonNode node : rootNode) {

                    String special = node.path("special").asText();
                    String infoFrom = node.path("infoFrom").asText();

                    if (!StringUtils.isEmpty(infoFrom) && "testTime".equals(infoFrom)) {
                        testTime = node.path("value").asInt(0);
                    }


                    if (!StringUtils.isEmpty(infoFrom) && "joinTimes".equals(infoFrom)) {
                        joinTimes = node.path("value").asInt(0);
                    }


                    if (!StringUtils.isEmpty(infoFrom) && "roiTimes".equals(infoFrom)) {
                        XRMCount = node.path("value").asInt(0);
                    }

                    if (!StringUtils.isEmpty(special) && "XRMNormal".equals(special)) {
                        // 与数量 有关 需要 1200 成时间 和 次数
                        isXRM = Boolean.TRUE;
                        isXRMNormal = Boolean.TRUE;
                    }else if (!StringUtils.isEmpty(special) && "XRMROI".equals(special)) {
                        isXRM = Boolean.TRUE;
                        isXRMNormal = Boolean.FALSE;
                    }

                }
                if (isXRM) {
                    // XRM费用计算逻辑
                    if (isXRMNormal) {
                        // isXRMNormal = true，根据prodCount计算，每个800元
                        addXRMFee = Arith.mul(800.0, XRMCount != null ? XRMCount : 1);
                    } else {
                        // isXRMNormal = false，统一收费500元
                        addXRMFee = Arith.mul(500.0, XRMCount != null ? XRMCount : 1);
                    }

                    // 计算时间相关费用：joinTimes * testTime转换为小时的费用
                    if (testTime > 0 && joinTimes > 0) {
                        // 计算时间费用，小于60分钟按1小时计算，超出部分按30分钟梯度计算
                        double timeFee = 0.0;
                        // 基础费用：1200元/小时
                        if (testTime <= 60) {
                            timeFee = 1200.0;
                        } else {
                            // 计算小时数，向上取整到0.5小时
                            double hours = Math.ceil(testTime / 30.0) * 0.5;
                            timeFee = Arith.mul(hours, 1200.0);
                        }

                        // 乘以joinTimes
                        timeFee = Arith.mul(timeFee, joinTimes);

                        // 将时间费用添加到addXRMFee
                        addXRMFee = Arith.add(addXRMFee, timeFee);
                    }
                }






                for (JsonNode node : rootNode) {
                    String infoFrom = node.path("infoFrom").asText();




                    // 处理infoFrom = many的情况
                    if ("many".equals(infoFrom)) {
                        JsonNode valueNode = node.path("value");
                        if (valueNode.isArray()) {
                            for (JsonNode itemNode : valueNode) {
                                if (itemNode.path("select").asBoolean(false)) {
                                    // 金额单位是分，需要转换为元
                                    double price = itemNode.path("price").asDouble(0.0);
                                    manyRelatedFee = Arith.add(manyRelatedFee, price);
                                }
                            }
                        }
                    }
                    // 处理infoFrom = needReturn的情况
                    else if ("needReturn".equals(infoFrom)) {
                        boolean needReturn = node.path("value").asBoolean(false);
                        if (needReturn) {
                            returnFee = 50.0;
                        }
                    }
                    // 处理infoFrom = needCloudVideo的情况
                    else if ("needCloudVideo".equals(infoFrom)) {
                        String valueStr = node.path("value").asText();
                        if (!valueStr.isEmpty()) {
                            try {
                                int minutes = Integer.parseInt(valueStr);
                                // 最低1小时起约
                                if (minutes <= 60 && minutes > 0) {
                                    cloudVideoFee = 80.0;
                                } else {
                                    // 超过1小时的部分以15分钟为梯度收费，每梯度20元
                                    // 不足15分钟的部分按照15分钟计算（向上取整）
                                    int extraMinutes = minutes - 60; // 超出1小时的分钟数
                                    int extraUnits = (int) Math.ceil(extraMinutes / 15.0); // 计算超出部分的梯度数（向上取整）
                                    double extraFee = extraUnits * 20.0; // 超出部分的费用
                                    cloudVideoFee = Arith.add(80.0, extraFee); // 总费用 = 基础费用(80元) + 超出部分费用
                                }
                            } catch (NumberFormatException e) {
                                // 处理无效的时间格式
                                throw new YamiShopBindException("云视频时间格式无效");
                            }
                        }
                    } else if ("etchingDepth".equals(infoFrom)) {
                        String valueStr = node.path("value").asText();
                        if (!valueStr.isEmpty()) {
                            try {
                                int minutes = Integer.parseInt(valueStr);
                                // 最低1小时起约
                                if (minutes <= 10 && minutes > 0) {
                                    cloudVideoFee = 100.0;
                                } else {
                                    // 超过1小时的部分以15分钟为梯度收费，每梯度20元
                                    // 不足15分钟的部分按照15分钟计算（向上取整）
                                    int extraMinutes = minutes - 10; // 超出1小时的分钟数
                                    int extraUnits = (int) Math.ceil(extraMinutes / 10.0); // 计算超出部分的梯度数（向上取整）
                                    double extraFee = extraUnits * 100.0; // 超出部分的费用
                                    cloudVideoFee = Arith.add(100.0, extraFee); // 总费用 = 基础费用(100元) + 超出部分费用
                                }
                            } catch (NumberFormatException e) {
                                // 处理无效的时间格式
                                throw new YamiShopBindException("切割深度长度无效");
                            }
                        }
                    } else if ("SEMTsetTime".equals(infoFrom)) {
                        String valueStr = node.path("value").asText();

                        if (!valueStr.isEmpty()) {
                            try {
                                int minutes = Integer.parseInt(valueStr);
                                // 最低1小时起约
                                if (minutes <= 60 && minutes > 0) {
                                    sEMTsetTimeFee = 1200.0;
                                } else {
                                    // 超过1小时的部分以15分钟为梯度收费，每梯度20元
                                    // 不足15分钟的部分按照15分钟计算（向上取整）
                                    int extraMinutes = minutes - 60; // 超出1小时的分钟数
                                    int extraUnits = (int) Math.ceil(extraMinutes / 15.0); // 计算超出部分的梯度数（向上取整）
                                    double extraFee = extraUnits * 300.0; // 超出部分的费用
                                    sEMTsetTimeFee = Arith.add(1200.0, extraFee); // 总费用 = 基础费用(80元) + 超出部分费用
                                }
                            } catch (NumberFormatException e) {
                                // 处理无效的时间格式
                                throw new YamiShopBindException("TEM时间格式无效");
                            }
                        }
                    }
                }
            }
        } catch (IOException e) {
            throw new YamiShopBindException("订单配置信息解析失败");
        }

        // 按照公式计算：(oriPrice + many相关金额总和 + needCloudVideo相关金额) * prodCount + needReturn相关金额 + XRM费用
        double subTotal = Arith.add(Arith.add(oriPrice != null ? oriPrice : 0.0, manyRelatedFee), cloudVideoFee);

        double totalFee = Arith.add(Arith.add(Arith.mul(subTotal, prodCount != null ? prodCount : 1), returnFee), addXRMFee);
        if (sEMTsetTimeFee > 0) {
            totalFee = Arith.add(totalFee, sEMTsetTimeFee);
        }
        return totalFee;
    }

    /**
     * 生成订单
     */
    @PostMapping("/confirm")
    @Operation(summary = "结算，生成订单信息" , description = "传入下单所需要的参数进行下单")
    public ServerResponseEntity<ShopCartOrderMergerDto> confirm(@Valid @RequestBody OrderParam orderParam) {
        String userId = SecurityUtils.getUser().getUserId();

        // 订单的地址信息
        UserAddr userAddr = userAddrService.getUserAddrByUserId(orderParam.getAddrId(), userId);
        UserAddrDto userAddrDto = BeanUtil.copyProperties(userAddr, UserAddrDto.class);


        // 组装获取用户提交的购物车商品项
        List<ShopCartItemDto> shopCartItems = basketService.getShopCartItemsByOrderItems(orderParam.getBasketIds(),orderParam.getOrderItem(),userId);

        if (CollectionUtil.isEmpty(shopCartItems)) {
            throw new YamiShopBindException("请选择您需要的商品加入购物车");
        }



        // 根据店铺组装购车中的商品信息，返回每个店铺中的购物车商品信息
        List<ShopCartDto> shopCarts = basketService.getShopCarts(shopCartItems);

        // 将要返回给前端的完整的订单信息
        ShopCartOrderMergerDto shopCartOrderMergerDto = new ShopCartOrderMergerDto();

        shopCartOrderMergerDto.setUserAddr(userAddrDto);

        // 所有店铺的订单信息
        List<ShopCartOrderDto> shopCartOrders = new ArrayList<>();

        double actualTotal = 0.0;
        double total = 0.0;
        int totalCount = 0;
        double orderReduce = 0.0;
        for (ShopCartDto shopCart : shopCarts) {
            // 每个店铺的订单信息
            ShopCartOrderDto shopCartOrder = new ShopCartOrderDto();
            shopCartOrder.setShopId(shopCart.getShopId());
            shopCartOrder.setShopName(shopCart.getShopName());


            List<ShopCartItemDiscountDto> shopCartItemDiscounts = shopCart.getShopCartItemDiscounts();

            // 店铺中的所有商品项信息
            List<ShopCartItemDto> shopAllShopCartItems = new ArrayList<>();
            for (ShopCartItemDiscountDto shopCartItemDiscount : shopCartItemDiscounts) {
                List<ShopCartItemDto> discountShopCartItems = shopCartItemDiscount.getShopCartItems();
                shopAllShopCartItems.addAll(discountShopCartItems);
            }

            shopCartOrder.setShopCartItemDiscounts(shopCartItemDiscounts);

            applicationContext.publishEvent(new ConfirmOrderEvent(shopCartOrder,orderParam,shopAllShopCartItems));

            // 计算额外费用
            double additionalFee = calculateAdditionalFee(shopAllShopCartItems.get(0).getPrice(),orderParam);

            actualTotal = additionalFee;
            total = additionalFee;
            totalCount = totalCount + orderParam.getOrderItem().getProdCount();
            orderReduce = Arith.add(orderReduce,shopCartOrder.getShopReduce());
            shopCartOrders.add(shopCartOrder);
            shopCartOrder.setTotal(total);
            shopCartOrder.setTotalCount(totalCount);
            shopCartOrder.setActualTotal(actualTotal);
            applicationContext.publishEvent(new ConfirmOrderEvent(shopCartOrder,orderParam,shopAllShopCartItems));

        }

        // 将额外费用添加到实际总金额中

        shopCartOrderMergerDto.setActualTotal(actualTotal);
        shopCartOrderMergerDto.setTotal(total);
        shopCartOrderMergerDto.setTotalCount(totalCount);
        shopCartOrderMergerDto.setShopCartOrders(shopCartOrders);
        shopCartOrderMergerDto.setOrderReduce(orderReduce);
        shopCartOrderMergerDto.setAdditionalFee(0.00);
        shopCartOrderMergerDto.setOrderConfigJson(orderParam.getOrderItem().getOrderConfigJson());
        shopCartOrderMergerDto.setSampleNo(orderParam.getOrderItem().getSampleNo());
        shopCartOrderMergerDto.setSampleName(orderParam.getOrderItem().getSampleName());
        shopCartOrderMergerDto.setSampleComposition(orderParam.getOrderItem().getSampleComposition());
        shopCartOrderMergerDto.setExtraFile(orderParam.getOrderItem().getExtraFile());
        shopCartOrderMergerDto.setContactPhone(orderParam.getOrderItem().getContactPhone());


        shopCartOrderMergerDto = orderService.putConfirmOrderCache(userId, shopCartOrderMergerDto);

        return ServerResponseEntity.success(shopCartOrderMergerDto);
    }

    /**
     * 购物车/立即购买  提交订单,根据店铺拆单
     */
    @PostMapping("/submit")
    @Operation(summary = "提交订单，返回支付流水号" , description = "根据传入的参数判断是否为购物车提交订单，同时对购物车进行删除，用户开始进行支付")
    public ServerResponseEntity<OrderNumbersDto> submitOrders(@Valid @RequestBody SubmitOrderParam submitOrderParam) {
        String userId = SecurityUtils.getUser().getUserId();
        ShopCartOrderMergerDto mergerOrder = orderService.getConfirmOrderCache(userId);
        if (mergerOrder == null) {
            throw new YamiShopBindException("订单已过期，请重新下单");
        }

        List<OrderShopParam> orderShopParams = submitOrderParam.getOrderShopParam();

        List<ShopCartOrderDto> shopCartOrders = mergerOrder.getShopCartOrders();
        // 设置备注
        if (CollectionUtil.isNotEmpty(orderShopParams)) {
            for (ShopCartOrderDto shopCartOrder : shopCartOrders) {
                for (OrderShopParam orderShopParam : orderShopParams) {
                    if (Objects.equals(shopCartOrder.getShopId(), orderShopParam.getShopId())) {
                        shopCartOrder.setRemarks(orderShopParam.getRemarks());
                    }
                }
            }
        }

        List<Order> orders = orderService.submit(userId,mergerOrder);



        StringBuilder orderNumbers = new StringBuilder();
        for (Order order : orders) {
            orderNumbers.append(order.getOrderNumber()).append(",");
        }
        orderNumbers.deleteCharAt(orderNumbers.length() - 1);

        boolean isShopCartOrder = false;
        // 移除缓存
        for (ShopCartOrderDto shopCartOrder : shopCartOrders) {
            for (ShopCartItemDiscountDto shopCartItemDiscount : shopCartOrder.getShopCartItemDiscounts()) {
                for (ShopCartItemDto shopCartItem : shopCartItemDiscount.getShopCartItems()) {
                    Long basketId = shopCartItem.getBasketId();
                    if (basketId != null && basketId != 0) {
                        isShopCartOrder = true;
                    }
                    skuService.removeSkuCacheBySkuId(shopCartItem.getSkuId(),shopCartItem.getProdId());
                    productService.removeProductCacheByProdId(shopCartItem.getProdId());
                }
            }
        }
        // 购物车提交订单时(即有购物车ID时)
        if (isShopCartOrder) {
            basketService.removeShopCartItemsCacheByUserId(userId);
        }
        orderService.removeConfirmOrderCache(userId);
        return ServerResponseEntity.success(new OrderNumbersDto(orderNumbers.toString()));
    }

}
